package website.haicheng.cloudauth.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import website.haicheng.cloudauth.dto.RoleInfoDto;
import website.haicheng.cloudauth.entity.RoleInfo;
import website.haicheng.cloudauth.entity.RoleMenu;
import website.haicheng.cloudauth.mapper.RoleInfoMapper;
import website.haicheng.cloudauth.mapper.RoleMenuMapper;
import website.haicheng.cloudauth.service.IRoleInfoService;
import website.haicheng.cloudauth.vo.RoleVo;
import website.haicheng.core.base.BaseQueryEntity;
import website.haicheng.core.constant.SysConstant;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 582895699@qq.com
 * @since 2021-02-10
 */
@Slf4j
@Service
public class RoleInfoServiceImpl extends ServiceImpl<RoleInfoMapper, RoleInfo> implements IRoleInfoService {


    @Autowired
    private RoleInfoMapper roleInfoMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;


    @Override
    public Set<String> listRoleName(int userId) {
        if (SysConstant.ROOT_ID == userId) {
            Set<String> strings = Sets.newHashSetWithExpectedSize(1);
            strings.add("*");
            return strings;
        }
        return roleInfoMapper.listRoleNameByUserId(userId);
    }

    @Override
    public IPage<RoleInfo> pageRoles(BaseQueryEntity queryEntity) {
        QueryWrapper<RoleInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RoleInfo::getIsDelete, false);
        queryWrapper.orderByAsc("id");
        return roleInfoMapper.selectPage(new Page<>(queryEntity.getCurrent(), queryEntity.getSize()), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addRole(RoleInfoDto dto, String createBy) {
        RoleInfo roleInfo = new RoleInfo();
        BeanUtils.copyProperties(dto, roleInfo);
        roleInfo.setCreateBy(createBy);
        roleInfo.setCreateTime(LocalDateTime.now());

        List<Long> permissions = dto.getPermissionIds();
        if (CollectionUtil.isNotEmpty(permissions)) {
            List<RoleMenu> list = Lists.newArrayListWithCapacity(permissions.size());
            permissions.forEach(item -> {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setMenuId(item);
                roleMenu.setRoleId(dto.getId());
                list.add(roleMenu);
            });
            roleMenuMapper.batchInsertRolePermissions(list);
        }
        roleInfoMapper.insert(roleInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateRole(RoleInfoDto dto, String modifyBy) {
        RoleInfo roleInfo = new RoleInfo();
        BeanUtils.copyProperties(dto, roleInfo);
        roleInfo.setModifyBy(modifyBy);
        roleInfo.setUpdateTime(LocalDateTime.now());

        QueryWrapper<RoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RoleMenu::getRoleId, dto.getId());
        roleMenuMapper.delete(queryWrapper);

        List<Long> permissions = dto.getPermissionIds();
        if (CollectionUtil.isNotEmpty(permissions)) {
            List<RoleMenu> list = Lists.newArrayListWithCapacity(permissions.size());
            permissions.forEach(item -> {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setMenuId(item);
                roleMenu.setRoleId(dto.getId());
                list.add(roleMenu);
            });
            roleMenuMapper.batchInsertRolePermissions(list);
        }
        roleInfoMapper.insert(roleInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delRole(long id, String modifyBy) {
        QueryWrapper<RoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RoleMenu::getRoleId, id);
        roleMenuMapper.delete(queryWrapper);

        RoleInfo roleInfo = new RoleInfo();
        roleInfo.setId(id);
        roleInfo.setIsDelete(true);
        roleInfo.setUpdateTime(LocalDateTime.now());
        roleInfo.setModifyBy(modifyBy);
        roleInfoMapper.updateById(roleInfo);
    }

    @Override
    public RoleVo getRoleAndPermission(long id) {
        QueryWrapper<RoleInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RoleInfo::getIsDelete, false);
        queryWrapper.lambda().eq(RoleInfo::getId, id);
        RoleInfo roleInfo = roleInfoMapper.selectOne(queryWrapper);

        RoleVo vo = new RoleVo();
        BeanUtils.copyProperties(roleInfo, vo);

        Set<Long> permissionIds = roleMenuMapper.listPermissionIds(id);
        vo.setPermissionIds(permissionIds);
        return vo;
    }
}
